package com.atguigu.gmall.seckill.core;

import com.atguigu.gmall.common.constants.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.common.util.JsonUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.biz.LocalCache;
import com.atguigu.gmall.seckill.service.SeckillGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author A
 * @version 1.0
 * @description: 定时任务
 * @date 2024/10/18 6:18
 */
@Slf4j
@Component
public class SeckillTask {
    @Autowired
    SeckillGoodsService seckillGoodsService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    LocalCache localCache;
    /*
     * @description: 定时上架秒杀商品到redis中
     * 秒 分 时 日 月 周
     * 每天晚上11点上架第二天天秒杀商品
     * @author: chensiwei
     * @date: 2024/10/18 6:19
     * @param: []
     * @return: void
     **/

    @Scheduled(cron = "0 * * * * ?")
    public void upSeckillGoods(){
//        //得到第二天时间
//        LocalDate plusDays = LocalDate.now().plusDays(1);
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//        //第二天
//        String plusDay = plusDays.format(dateTimeFormatter);
        log.info("执行定时秒杀任务");
        String currentTime = DateUtil.formatDate(new Date());
        //从数据库查
        List<SeckillGoods> goodsList =seckillGoodsService.getFocusSecKillGoodsList(currentTime);
        String seckillGoods = JsonUtil.obj2Json(goodsList);
        //存入缓存,key为时间
        //hashmap结构 key: skuId  goodsInfo
        BoundHashOperations<String, String, String> seckillGoodsBound = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS_CACHE_PREFIX + currentTime);
        //设置一天过期时间
        seckillGoodsBound.expire(1,TimeUnit.DAYS);
        goodsList.forEach(goods -> {
            seckillGoodsBound.put(goods.getSkuId().toString(),JsonUtil.obj2Json(goods));
        });
        //上架库存信号量
        upStockSemaphore(goodsList,currentTime);

        //设置一级缓存(本地缓存)
        localCache.setCache(goodsList);
    }
    //上架库存信号量
    private void upStockSemaphore(List<SeckillGoods> goodsList, String currentTime) {
        log.info("上架库存信号量");
        goodsList.forEach(item->{
            Long skuId = item.getSkuId();
            Integer stockCount = item.getStockCount();
            String semaphoreKey = RedisConst.SECKILL_GOODS_CACHE_PREFIX + currentTime + ":" + skuId;
            RSemaphore semaphore = redissonClient.getSemaphore(semaphoreKey);
            //初始化库存,设置库存信号
            semaphore.trySetPermits(stockCount);
        });
    }


}


